home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume6 / shadow-2.pt3 < prev    next >
Encoding:
Text File  |  1989-02-03  |  31.7 KB  |  1,596 lines

  1. Path: xanth!nic.MR.NET!csd4.milw.wisc.edu!leah!itsgw!steinmetz!uunet!allbery
  2. From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  3. Newsgroups: comp.sources.misc
  4. Subject: v06i024: shadow password routines, part 3 of ???
  5. Message-ID: <47756@uunet.UU.NET>
  6. Date: 29 Jan 89 21:14:21 GMT
  7. Sender: allbery@uunet.UU.NET
  8. Reply-To: jfh@hal.CWRU.Edu@convex.UUCP (John F. Haugh II)
  9. Lines: 1584
  10. Approved: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  11.  
  12. Posting-number: Volume 6, Issue 24
  13. Submitted-by: jfh@hal.CWRU.Edu@convex.UUCP (John F. Haugh II)
  14. Archive-name: shadow-2.pt3
  15.  
  16. [See part 1 for information (part 2 for my lament).  ++bsa]
  17.  
  18. #! /bin/sh
  19. # This is a shell archive, meaning:
  20. # 1. Remove everything above the #! /bin/sh line.
  21. # 2. Save the resulting text in a file.
  22. # 3. Execute the file with /bin/sh (not csh) to create:
  23. #    lastlog.h
  24. #    login.c
  25. #    motd.c
  26. #    password.c
  27. #    shell.c
  28. #    utmp.c
  29. #    age.c
  30. #    env.c
  31. #    pwent.c
  32. #    shadow.c
  33. #    valid.c
  34. #    lmain.c
  35. #    smain.c
  36. #    pwconv.c
  37. #    dialup.c
  38. #    dialchk.c
  39. #    pwunconv.c
  40. # This archive created: Sun Jan 22 22:24:55 1989
  41. # By:    John F. Haugh II (River Parishes Programming, Dallas TX)
  42. export PATH; PATH=/bin:/usr/bin:$PATH
  43. if test -f 'lastlog.h'
  44. then
  45.     echo shar: "will not over-write existing file 'lastlog.h'"
  46. else
  47. cat << \SHAR_EOF > 'lastlog.h'
  48. /*
  49.  * lastlog.h - structure of lastlog file
  50.  *
  51.  *    This file defines a lastlog file structure which should be sufficient
  52.  *    to hold the information required by login.  It should only be used if
  53.  *    there is no real lastlog.h file.
  54.  */
  55.  
  56. struct    lastlog    {
  57.     time_t    ll_time;
  58.     char    ll_line[8];
  59. };
  60. SHAR_EOF
  61. fi
  62. if test -f 'login.c'
  63. then
  64.     echo shar: "will not over-write existing file 'login.c'"
  65. else
  66. cat << \SHAR_EOF > 'login.c'
  67. #include <stdio.h>
  68. #include <ctype.h>
  69. #include <string.h>
  70.  
  71. void    setenv ();
  72.  
  73. void    login (name)
  74. char    *name;
  75. {
  76.     char    buf[BUFSIZ];
  77.     char    *envp[32];
  78.     int    envc;
  79.     char    *cp;
  80.     int    i;
  81.  
  82.     memset (buf, 0, BUFSIZ);
  83.  
  84.     fputs ("login: ", stdout);
  85.  
  86.     if (fgets (buf, BUFSIZ, stdin) != buf)
  87.         exit (1);
  88.  
  89.     buf[strlen (buf) - 1] = '\0';    /* remove \n [ must be there ] */
  90.  
  91.     for (cp = buf;*cp == ' ' || *cp == '\t';cp++)
  92.         ;
  93.  
  94.     for (i = 0;i < BUFSIZ - 1 && isgraph (*cp);name[i++] = *cp++)
  95.         ;
  96.  
  97.     if (*cp)
  98.         cp++;
  99.  
  100.     name[i] = '\0';
  101.  
  102.     if (*cp != '\0') {        /* process new variables */
  103.         for (envc = 0;envc < 32;envc++) {
  104.             envp[envc] = strtok (envc == 0 ? cp:(char *) 0, " \t,");
  105.  
  106.             if (envp[envc] == (char *) 0)
  107.                 break;
  108.         }
  109.         setenv (envc, envp);
  110.     }
  111. }
  112. SHAR_EOF
  113. fi
  114. if test -f 'motd.c'
  115. then
  116.     echo shar: "will not over-write existing file 'motd.c'"
  117. else
  118. cat << \SHAR_EOF > 'motd.c'
  119. #include <stdio.h>
  120. #include <string.h>
  121. #include "config.h"
  122.  
  123. extern    char    home[];
  124.  
  125. void    motd ()
  126. {
  127. #ifdef    MOTD
  128.     FILE    *fp;
  129.     register int    c;
  130. #ifdef    HUSHLOGIN
  131.     char    hush[BUFSIZ];
  132.  
  133.     (void) strcat (strcpy (hush, home + 5), "/.hushlogin");
  134.  
  135.     if (access (hush, 0) == 0)
  136.         return;
  137. #endif
  138.     if ((fp = fopen ("/etc/motd", "r")) == (FILE *) 0)
  139.         return;
  140.  
  141.     while ((c = getc (fp)) != EOF)
  142.         putchar (c);
  143.  
  144.     fclose (fp);
  145.     fflush (stdout);
  146. #endif
  147. }
  148. SHAR_EOF
  149. fi
  150. if test -f 'password.c'
  151. then
  152.     echo shar: "will not over-write existing file 'password.c'"
  153. else
  154. cat << \SHAR_EOF > 'password.c'
  155. #include <stdio.h>
  156. #include <string.h>
  157. #include <termio.h>
  158. #include <fcntl.h>
  159.  
  160. /*
  161.  * password - prompt for password and return entry
  162.  *
  163.  *    Need to fake up getpass().  Returns TRUE if a password
  164.  *    was successfully input, and FALSE otherwise, including
  165.  *    EOF on input or ioctl() failure.  pass is not modified
  166.  *    on failure.
  167.  */
  168.  
  169. int    password (prompt, pass)
  170. char    *prompt;
  171. char    *pass;
  172. {
  173.     char    buf[BUFSIZ];
  174.     int    eof;
  175.     int    ttyopened = 0;
  176.     struct    termio    termio;
  177.     struct    termio    save;
  178.     FILE    *fp;
  179.  
  180.     if ((fp = fopen ("/dev/tty", "r")) == (FILE *) 0)
  181.         fp = stdin;
  182.     else
  183.         ttyopened = 1;
  184.  
  185.     if (ioctl (fileno (fp), TCGETA, &termio))
  186.         return (0);
  187.  
  188.     save = termio;
  189.     termio.c_lflag &= ~ECHO;
  190.     ioctl (fileno (fp), TCSETAF, &termio);
  191.  
  192.     fputs (prompt, stdout);
  193.     eof = gets (buf) == (char *) 0 || feof (fp) || ferror (fp);
  194.     putchar ('\n');
  195.  
  196.     ioctl (fileno (fp), TCSETAF, &save);
  197.  
  198.     if (! eof) {
  199.         buf[8] = '\0';
  200.         (void) strcpy (pass, buf);
  201.     }
  202.     if (ttyopened)
  203.         fclose (fp);
  204.  
  205.     return (! eof);
  206. }
  207. SHAR_EOF
  208. fi
  209. if test -f 'shell.c'
  210. then
  211.     echo shar: "will not over-write existing file 'shell.c'"
  212. else
  213. cat << \SHAR_EOF > 'shell.c'
  214. #include <stdio.h>
  215. #include <string.h>
  216. #include "config.h"
  217.  
  218. extern    char    *newenvp[];
  219.  
  220. void    shell (file)
  221. char    *file;
  222. {
  223.     char    arg0[BUFSIZ];
  224. #ifndef    SU
  225.     char    *path;
  226. #endif
  227.     char    *strrchr ();
  228.     extern    int    errno;
  229.  
  230.     if (file == (char *) 0)
  231.         exit (1);
  232.  
  233. #ifndef    SU
  234.     if (path = strrchr (file, '/'))
  235.         path++;
  236.     else
  237.         path = file;
  238.  
  239.     (void) strcpy (arg0 + 1, path);
  240.     arg0[0] = '-';
  241. #else
  242.     (void) strcpy (arg0, "-su");
  243. #endif
  244. #ifndef    NDEBUG
  245.     printf ("Executing shell %s\n", file);
  246. #endif
  247.     execle (file, arg0, (char *) 0, newenvp);
  248.     printf ("Can't execute %s\n", file);
  249.     exit (errno);
  250. }
  251. SHAR_EOF
  252. fi
  253. if test -f 'utmp.c'
  254. then
  255.     echo shar: "will not over-write existing file 'utmp.c'"
  256. else
  257. cat << \SHAR_EOF > 'utmp.c'
  258. #include <sys/types.h>
  259. #include <utmp.h>
  260. #include <string.h>
  261. #include <stdio.h>
  262. #include "config.h"
  263.  
  264. extern    struct    utmp    utent;
  265. extern    char    name[];
  266.  
  267. struct    utmp    *getutent ();
  268. void    setutent ();
  269. void    endutent ();
  270. void    pututline ();
  271. char    *memset ();
  272. time_t    time ();
  273.  
  274. void    checkutmp ()
  275. {
  276.     struct    utmp    *ut;
  277. #ifndef    NDEBUG
  278.     int    pid = getppid ();
  279. #else
  280.     int    pid = getpid ();
  281. #endif
  282.     setutent ();
  283.  
  284.     while (ut = getutent ())
  285.         if (ut->ut_pid == pid)
  286.             break;
  287.  
  288.     if (ut)
  289.         utent = *ut;
  290.  
  291.     endutent ();
  292.  
  293.     if (ut && utent.ut_pid == pid)
  294.         return;
  295.  
  296.     puts ("No utmp entry.  You must exec \"login\" from the lowest level \"sh\"");
  297.     exit (1);
  298. }
  299.  
  300. void    setutmp ()
  301. {
  302.     FILE    *wtmp;
  303.     char    tty[sizeof utent.ut_line + 1];
  304.     char    *line;
  305.  
  306.     setutent ();
  307.  
  308.     (void) strncpy (utent.ut_user, name, sizeof utent.ut_user);
  309.  
  310.     utent.ut_type = USER_PROCESS;
  311.  
  312.     if (line = strrchr (utent.ut_line, '/')) {
  313.         (void) strcpy (tty, line + 1);
  314.         (void) memset (utent.ut_line, '\0', sizeof utent.ut_line);
  315.         (void) strcpy (utent.ut_line, tty);
  316.     }
  317.     (void) time (&utent.ut_time);
  318.  
  319.     pututline (&utent);
  320.     endutent ();
  321.  
  322.     if ((wtmp = fopen (WTMP_FILE, "a+"))) {
  323.         fwrite (&utent, sizeof utent, 1, wtmp);
  324.         fclose (wtmp);
  325.     }
  326. }
  327. SHAR_EOF
  328. fi
  329. if test -f 'age.c'
  330. then
  331.     echo shar: "will not over-write existing file 'age.c'"
  332. else
  333. cat << \SHAR_EOF > 'age.c'
  334. #include <sys/types.h>
  335. #include <stdio.h>
  336. #include <pwd.h>
  337. #include "config.h"
  338.  
  339. #ifndef    PASSWD
  340. extern    char    *newenvp[];
  341. #endif
  342.  
  343. time_t    time ();
  344.  
  345. #ifdef    AGING
  346. #ifdef    PASSWD
  347. char    *l64a (l)
  348. long    l;
  349. {
  350.     static    char    buf[8];
  351.     int    i = 0;
  352.  
  353.     if (i < 0L)
  354.         return ((char *) 0);
  355.  
  356.     do {
  357.         buf[i++] = i64c ((int) (l % 64));
  358.         buf[i] = '\0';
  359.     } while (l /= 64L, l > 0 && i < 6);
  360.  
  361.     return (buf);
  362. }
  363. #endif
  364. int    i64c (i)
  365. int    i;
  366. {
  367.     if (i < 0)
  368.         return ('.');
  369.     else if (i > 63)
  370.         return ('z');
  371.  
  372.     if (i == 0)
  373.         return ('.');
  374.  
  375.     if (i == 1)
  376.         return ('/');
  377.  
  378.     if (i >= 2 && i <= 11)
  379.         return ('0' - 2 + i);
  380.  
  381.     if (i >= 12 && i <= 37)
  382.         return ('A' - 12 + i);
  383.  
  384.     if (i >= 38 && i <= 63)
  385.         return ('a' - 38 + i);
  386.  
  387.     return ('\0');
  388. }
  389.  
  390. int    c64i (c)
  391. char    c;
  392. {
  393.     if (c == '.')
  394.         return (0);
  395.  
  396.     if (c == '/')
  397.         return (1);
  398.  
  399.     if (c >= '0' && c <= '9')
  400.         return (c - '0' + 2);
  401.  
  402.     if (c >= 'A' && c <= 'Z')
  403.         return (c - 'A' + 12);
  404.  
  405.     if (c >= 'a' && c <= 'z')
  406.         return (c - 'a' + 38);
  407.     else
  408.         return (-1);
  409. }
  410.  
  411. long    a64l (s)
  412. char    *s;
  413. {
  414.     int    i;
  415.     long    value;
  416.     long    shift = 0;
  417.  
  418.     for (i = 0, value = 0L;i < 6 && *s;s++) {
  419.         value += (c64i (*s) << shift);
  420.         shift += 6;
  421.     }
  422.     return (value);
  423. }
  424. #ifndef    PASSWD
  425. void    expire (age)
  426. char    *age;
  427. {
  428.     long    clock;
  429.     long    week;
  430.     extern    char    name[];
  431.     extern    int    errno;
  432.  
  433.     (void) time (&clock);
  434.     clock /= (7L * 24L * 60L * 60L);
  435.  
  436.     if (strlen (age) < 4)
  437.         week = 0L;
  438.     else
  439.         week = a64l (age + 2);
  440.  
  441.     if (clock >= week + c64i (age[0])) {
  442.         printf ("Your password has expired.");
  443.  
  444.         if (c64i (age[0]) < c64i (age[1])) {
  445.             puts ("  Contact the system administrator.\n");
  446.             exit (1);
  447.         }
  448.         puts ("  Choose a new one.\n");
  449.  
  450.         execl ("/bin/passwd", "-passwd", name, (char *) 0);
  451.         puts ("Can't execute /bin/passwd");
  452.         exit (errno);
  453.     }
  454. }
  455. #endif
  456. #endif
  457. SHAR_EOF
  458. fi
  459. if test -f 'env.c'
  460. then
  461.     echo shar: "will not over-write existing file 'env.c'"
  462. else
  463. cat << \SHAR_EOF > 'env.c'
  464. #include <stdio.h>
  465. #include <string.h>
  466.  
  467. extern    char    **environ;
  468. extern    char    *newenvp[];
  469. extern    int    newenvc;
  470. extern    int    maxenv;
  471.  
  472. char    *strdup ();
  473. void    free ();
  474.  
  475. static    char    *forbid[] = {
  476.     "HOME",
  477.     "IFS",
  478.     "PATH",
  479.     "SHELL",
  480.     (char *) 0
  481. };
  482.  
  483. void    addenv (entry)
  484. char    *entry;
  485. {
  486.     char    *cp;
  487.     int    i;
  488.     int    len;
  489.  
  490.     if (cp = strchr (entry, '='))
  491.         len = cp - entry;
  492.     else
  493.         len = strlen (entry);
  494.  
  495.     for (i = 0;i < newenvc;i++)
  496.         if (strncmp (entry, newenvp[i], len) == 0 &&
  497.             (newenvp[i][len] == '=' || newenvp[i][len] == '\0'))
  498.             break;
  499.  
  500.     if (i == maxenv) {
  501.         puts ("Environment overflow");
  502.         return;
  503.     }
  504.     if (i == newenvc) {
  505.         newenvp[newenvc++] = strdup (entry);
  506.     } else {
  507.         free (newenvp[i]);
  508.         newenvp[i] = strdup (entry);
  509.     }
  510. }
  511.  
  512. void    setenv (argc, argv)
  513. int    argc;
  514. char    **argv;
  515. {
  516.     int    i;
  517.     int    n;
  518.     char    variable[BUFSIZ];
  519.     char    *cp;
  520.  
  521.     for (i = 0;i < argc;i++) {
  522.         if ((n = strlen (argv[i])) >= BUFSIZ)
  523.             continue;    /* ignore long entries */
  524.  
  525.         if (! (cp = strchr (argv[i], '='))) {
  526.             (void) strcpy (variable, argv[i]);
  527.         } else {
  528.             (void) strncpy (variable, argv[i], cp - argv[i]);
  529.             variable[cp - argv[i]] = '\0';
  530.         }
  531.         for (n = 0;forbid[n] != (char *) 0;n++)
  532.             if (strcmp (variable, forbid[n]) == 0)
  533.                 break;
  534.  
  535.         if (forbid[n] != (char *) 0) {
  536.             printf ("You may not change $%s\n", forbid[n]);
  537.             continue;
  538.         }
  539.         addenv (argv[i]);
  540.     }
  541. }
  542. SHAR_EOF
  543. fi
  544. if test -f 'pwent.c'
  545. then
  546.     echo shar: "will not over-write existing file 'pwent.c'"
  547. else
  548. cat << \SHAR_EOF > 'pwent.c'
  549. #include <stdio.h>
  550. #include <pwd.h>
  551. #include <string.h>
  552.  
  553. #define    SBUFSIZ    64
  554.  
  555. static    char    *tokcpy (buf, token)
  556. char    *buf;
  557. char    *token;
  558. {
  559.     static    char    *cp;
  560.     char    *start;
  561.  
  562.     if (buf == (char *) 0)
  563.         buf = cp;
  564.     else
  565.         cp = buf;
  566.  
  567.     start = cp;
  568.  
  569.     if (*buf == '\0')
  570.         return ((char *) 0);
  571.  
  572.     while (*buf && *buf != ':')
  573.         *token++ = *buf++;
  574.  
  575.     *token = '\0';
  576.  
  577.     if (*buf)
  578.         cp = buf + 1;
  579.  
  580.     return (start);
  581. }
  582.  
  583. struct    passwd    *sgetpwent (buf)
  584. char    *buf;
  585. {
  586.     static    struct    passwd    pwent;
  587.     static    char    name[SBUFSIZ];
  588.     static    char    password[SBUFSIZ];
  589.     static    char    gecos[SBUFSIZ];
  590.     static    char    home[SBUFSIZ];
  591.     static    char    shell[SBUFSIZ];
  592.     static    char    age[SBUFSIZ];
  593.     char    tmp[BUFSIZ];
  594.     char    *cp;
  595.  
  596.     pwent.pw_name = name;
  597.     pwent.pw_passwd = password;
  598.     pwent.pw_uid = -1;
  599.     pwent.pw_gid = -1;
  600.     pwent.pw_age = age;
  601.     pwent.pw_comment = (char *) 0;
  602.     pwent.pw_gecos = gecos;
  603.     pwent.pw_dir = home;
  604.     pwent.pw_shell = shell;
  605.  
  606.     (void) strcpy (tmp, buf);
  607.  
  608.     if (! tokcpy (tmp, name) || ! name[0])
  609.         return ((struct passwd *) 0);
  610.  
  611.     if (! tokcpy ((char *) 0, password))
  612.         return ((struct passwd *) 0);
  613.  
  614.     if (tokcpy ((char *) 0, tmp) && *tmp)
  615.         pwent.pw_uid = atoi (tmp);
  616.     else
  617.         return ((struct passwd *) 0);
  618.  
  619.     if (tokcpy ((char *) 0, tmp) && *tmp)
  620.         pwent.pw_gid = atoi (tmp);
  621.     else
  622.         return ((struct passwd *) 0);
  623.  
  624.     if (cp = strchr (password, ',')) {
  625.         (void) strcpy (age, cp + 1);
  626.         *cp = '\0';
  627.     } else
  628.         pwent.pw_age = (char *) 0;
  629.  
  630.     if (! tokcpy ((char *) 0, gecos))
  631.         return ((struct passwd *) 0);
  632.  
  633.     if (! tokcpy ((char *) 0, home))
  634.         return ((struct passwd *) 0);
  635.  
  636.     if (! tokcpy ((char *) 0, shell) && *shell)
  637.         pwent.pw_shell = (char *) 0;
  638.  
  639.     if (pwent.pw_passwd && pwent.pw_passwd[0] == '\0')
  640.         pwent.pw_passwd = (char *) 0;
  641.  
  642.     return (&pwent);
  643. }
  644. #ifdef FGETPWENT
  645. struct    passwd    *fgetpwent (fp)
  646. FILE    *fp;
  647. {
  648.     char    buf[BUFSIZ];
  649.  
  650.     while (fgets (buf, BUFSIZ, fp) != (char *) 0) {
  651.         if (buf[0] == '#')
  652.             continue;
  653.  
  654.         buf[strlen (buf) - 1] = '\0';
  655.         return (sgetpwent (buf));
  656.     }
  657.     return ((struct passwd *) 0);
  658. }
  659. #endif
  660. SHAR_EOF
  661. fi
  662. if test -f 'shadow.c'
  663. then
  664.     echo shar: "will not over-write existing file 'shadow.c'"
  665. else
  666. cat << \SHAR_EOF > 'shadow.c'
  667. #include "shadow.h"
  668. #include <stdio.h>
  669. #include <string.h>
  670.  
  671. static    FILE    *shadow;
  672.  
  673. void    setspent ()
  674. {
  675.     if (shadow)
  676.         rewind (shadow);
  677.     else
  678.         shadow = fopen (SHADOW, "r");
  679. }
  680.  
  681. void    endspent ()
  682. {
  683.     if (shadow)
  684.         (void) fclose (shadow);
  685.  
  686.     shadow = (FILE *) 0;
  687. }
  688.  
  689. struct    spwd    *fgetspent (fp)
  690. FILE    *fp;
  691. {
  692.     static    struct    spwd    spwd;
  693.     static    char    name[32];
  694.     static    char    pass[32];
  695.     char    buf[BUFSIZ];
  696.     char    *cp;
  697.     int    atoi ();
  698.     long    atol ();
  699.  
  700.     if (! fp)
  701.         return (0);
  702.  
  703.     if (fgets (buf, BUFSIZ, fp) == (char *) 0)
  704.         return (0);
  705.  
  706.     buf[strlen (buf) - 1] = '\0';
  707.  
  708.     if ((cp = strtok (buf, ":")) && *cp)
  709.         (void) strcpy (name, cp);
  710.     else
  711.         return (0);
  712.  
  713.     if ((cp = strtok ((char *) 0, ":")) && *cp)
  714.         (void) strcpy (pass, cp);
  715.     else
  716.         return (0);
  717.  
  718.     if ((cp = strtok ((char *) 0, ":")) && *cp)
  719.         spwd.sp_lstchg = atol (cp);
  720.     else
  721.         return (0);
  722.  
  723.     if ((cp = strtok ((char *) 0, ":")) && *cp)
  724.         spwd.sp_min = atoi (cp);
  725.     else
  726.         return (0);
  727.  
  728.     if ((cp = strtok ((char *) 0, ":")) && *cp)
  729.         spwd.sp_max = atoi (cp);
  730.     else
  731.         return (0);
  732.  
  733.     spwd.sp_namp = name;
  734.     spwd.sp_pwdp = pass;
  735.  
  736.     return (&spwd);
  737. }
  738.  
  739. struct    spwd    *getspent ()
  740. {
  741.     if (! shadow)
  742.         setspent ();
  743.  
  744.     return (fgetspent (shadow));
  745. }
  746.  
  747. struct    spwd    *getspnam (name)
  748. char    *name;
  749. {
  750.     struct    spwd    *spwd;
  751.  
  752.     setspent ();
  753.  
  754.     while ((spwd = getspent ()) != (struct spwd *) 0) {
  755.         if (strcmp (name, spwd->sp_namp) == 0)
  756.             return (spwd);
  757.     }
  758.     return (0);
  759. }
  760.  
  761. int    putspent (spwd, fp)
  762. struct    spwd    *spwd;
  763. FILE    *fp;
  764. {
  765.     if (! fp)
  766.         return (0);
  767.  
  768.     return (fprintf (fp, "%s:%s:%ld:%d:%d\n",
  769.             spwd->sp_namp, spwd->sp_pwdp,
  770.             spwd->sp_lstchg, spwd->sp_min, spwd->sp_max) != EOF);
  771. }
  772. SHAR_EOF
  773. fi
  774. if test -f 'valid.c'
  775. then
  776.     echo shar: "will not over-write existing file 'valid.c'"
  777. else
  778. cat << \SHAR_EOF > 'valid.c'
  779. #include <pwd.h>
  780.  
  781. /*
  782.  * valid - compare encrypted passwords
  783.  *
  784.  *    Valid() compares the DES encrypted password from the password file
  785.  *    against the password which the user has entered after it has been
  786.  *    encrypted using the same salt as the original.
  787.  */
  788.  
  789. int    valid (password, entry)
  790. char    *password;
  791. struct    passwd    *entry;
  792. {
  793.     char    *encrypt;
  794.     char    *salt;
  795.     char    *crypt ();
  796.  
  797.     /*
  798.      * Start with blank or empty password entries.  Always encrypt
  799.      * a password if no such user exists.  Only if the ID exists and
  800.      * the password is really empty do you return quickly.  This
  801.      * routine is meant to waste CPU time.
  802.      */
  803.  
  804.     if (entry->pw_name &&
  805.             (entry->pw_passwd == (char *) 0 ||
  806.              strlen (entry->pw_passwd) == 0)) {
  807.         if (strlen (password) == 0)
  808.             return (1);    /* user entered nothing */
  809.         else
  810.             return (0);    /* user entered something! */
  811.     }
  812.  
  813.     /*
  814.      * If there is no entry then we need a salt to use.
  815.      */
  816.  
  817.     if (entry->pw_passwd == (char *) 0 || entry->pw_passwd[0] == '\0')
  818.         salt = "xx";
  819.     else
  820.         salt = entry->pw_passwd;
  821.  
  822.     /*
  823.      * Now, perform the encryption using the salt from before on
  824.      * the users input.  Since we always encrypt the string, it
  825.      * should be very difficult to determine if the user exists by
  826.      * looking at execution time.
  827.      */
  828.  
  829.     encrypt = crypt (password, salt);
  830.  
  831.     /*
  832.      * One last time we must deal with there being no password file
  833.      * entry for the user.  We use the pw_passwd == NULL idiom to
  834.      * cause non-existent users to not be validated.  Even still,
  835.      * we are safe because if the string were == "", any encrypted
  836.      * string is not going to match - the output of crypt() begins
  837.      * with the salt, which is "xx", not "".
  838.      */
  839.  
  840.     if (entry->pw_passwd && strcmp (encrypt, entry->pw_passwd) == 0)
  841.         return (1);
  842.     else
  843.         return (0);
  844. }
  845. SHAR_EOF
  846. fi
  847. if test -f 'lmain.c'
  848. then
  849.     echo shar: "will not over-write existing file 'lmain.c'"
  850. else
  851. cat << \SHAR_EOF > 'lmain.c'
  852. #include <sys/types.h>
  853. #include <stdio.h>
  854. #include <pwd.h>
  855. #include <utmp.h>
  856. #include <time.h>
  857. #include <string.h>
  858. #include <signal.h>
  859. #include "config.h"
  860. #include "lastlog.h"
  861.  
  862. char    name[BUFSIZ];
  863. char    pass[BUFSIZ];
  864. char    home[BUFSIZ];
  865. char    prog[BUFSIZ];
  866. char    mail[BUFSIZ];
  867.  
  868. struct    passwd    pwent;
  869. struct    utmp    utent;
  870. struct    lastlog    lastlog;
  871.  
  872. #ifndef    MAXENV
  873. #define    MAXENV    64
  874. #endif
  875.  
  876. char    *newenvp[MAXENV];
  877. int    newenvc = 0;
  878. int    maxenv = MAXENV;
  879. extern    char    **environ;
  880.  
  881. char    *getenv ();
  882. char    *memset ();
  883. void    checkutmp ();
  884. void    addenv ();
  885. void    setenv ();
  886. unsigned alarm ();
  887. void    login ();
  888. void    entry ();
  889. void    setutmp ();
  890. void    subsystem ();
  891. void    log ();
  892. void    setup ();
  893. void    expire ();
  894. void    motd ();
  895. void    mailcheck ();
  896. void    shell ();
  897.  
  898. #ifndef    ALARM
  899. #define    ALARM    60
  900. #endif
  901.  
  902. #ifndef    RETRIES
  903. #define    RETRIES    3
  904. #endif
  905.  
  906. int    main (argc, argv, envp)
  907. int    argc;
  908. char    **argv;
  909. char    **envp;
  910. {
  911.     int    retries = RETRIES;
  912.  
  913.     checkutmp ();            /* must be lowest level shell */
  914.  
  915.     if (! isatty (0))        /* must be a terminal */
  916.         exit (1);
  917.  
  918.     while (*envp)            /* add inherited environment, */
  919.         addenv (*envp++);    /* some variables change later */
  920.  
  921. #ifdef    TZ
  922.     addenv (TZ);            /* set the default $TZ, if one */
  923. #endif
  924. #ifdef    HZ
  925.     addenv (HZ);            /* set the default $HZ, if one */
  926. #endif
  927.     if (argc >= 2) {        /* now set command line variables */
  928.         setenv (argc - 2, &argv[2]);
  929.         (void) strncpy (name, argv[1], sizeof name);
  930.     }
  931.     (void) alarm (ALARM);        /* only allow ALARM sec. for login */
  932.  
  933.     while (1) {        /* repeatedly get login/password pairs */
  934.         if (! name[0]) {    /* need to get a login id */
  935.             login (name);
  936.             continue;
  937.         }
  938.         entry (name, &pwent);    /* get entry from password file */
  939.  
  940.     /*
  941.      * Here we have a sticky situation.  Some accounts may have no
  942.      * password entry in the password file.  So, we don't ask for a
  943.      * password.  Others, have a blank password entered - you be the
  944.      * judge.  The conditional compilation NOBLANK requires even
  945.      * blank passwords to be prompted for.  This may well break
  946.      * quite a few systems.  Use with discretion.
  947.      */
  948.  
  949. #ifdef    NOBLANK
  950.                     /* get a password from user */
  951.         if (! password ("Password:", pass))
  952.             continue;
  953. #else
  954.         if ((! pwent.pw_name || pwent.pw_passwd)
  955.                     && ! password ("Password:", pass))
  956.             continue;
  957. #endif
  958.         if (valid (pass, &pwent)) /* check encrypted passwords ... */
  959.             break;        /* ... encrypted passwords matched */
  960.  
  961.         if (--retries <= 0)    /* only allow so many failures */
  962.             exit (1);
  963.  
  964.         puts ("Login incorrect");
  965.         (void) memset (name, '\0', sizeof name);
  966.     }
  967. #ifdef    DIALUP
  968.     if (! dialcheck (utent.ut_line,
  969.             pwent.pw_shell ? pwent.pw_shell:"/bin/sh")) {
  970.         puts ("Dialup password incorrect");
  971.         exit (1);
  972.     }
  973. #endif
  974.     (void) alarm (0);        /* turn off alarm clock */
  975.     environ = newenvp;        /* make new environment active */
  976.  
  977.     if (getenv ("IFS"))        /* don't export user IFS ... */
  978.         addenv ("IFS= \t\n");    /* ... instead, set a safe IFS */
  979.  
  980.     setutmp ();            /* make entry in utmp & wtmp files */
  981. #ifdef    CONSOLE
  982.     if (pwent.pw_uid == 0 &&    /* root no logging in on console ? */
  983.             strncmp (CONSOLE, utent.ut_line, sizeof utent.ut_line))
  984.         exit (1);        /* then exit! */
  985. #endif
  986.     if (pwent.pw_shell[0] == '*')    /* subsystem root required */
  987.         subsystem ();        /* figure out what to execute */
  988.  
  989. #ifdef    LASTLOG
  990.     log ();                /* give last login and log this one */
  991. #endif
  992.     setup (&pwent);            /* set UID, GID, HOME, etc ... */
  993. #ifdef    AGING
  994.     if (pwent.pw_age)        /* check for age of password ... */
  995.         expire (pwent.pw_age);    /* ... ask for new one if expired */
  996. #endif
  997. #ifdef    MOTD
  998.     motd ();            /* print the message of the day */
  999. #endif
  1000. #ifdef    LASTLOG
  1001.     if (lastlog.ll_time != 0)
  1002.         printf ("Last login: %.19s on %s\n",
  1003.             ctime (&lastlog.ll_time), lastlog.ll_line);
  1004. #endif
  1005. #ifdef    MAILCHECK
  1006.     mailcheck ();            /* report on the status of mail */
  1007. #endif
  1008.     signal (SIGINT, SIG_DFL);    /* default interrupt signal */
  1009.     signal (SIGQUIT, SIG_DFL);    /* default quit signal */
  1010.     signal (SIGTERM, SIG_DFL);    /* default terminate signal */
  1011.     signal (SIGALRM, SIG_DFL);    /* default alarm signal */
  1012.  
  1013.     shell (pwent.pw_shell);        /* exec the shell finally. */
  1014.     /*NOTREACHED*/
  1015. }
  1016. SHAR_EOF
  1017. fi
  1018. if test -f 'smain.c'
  1019. then
  1020.     echo shar: "will not over-write existing file 'smain.c'"
  1021. else
  1022. cat << \SHAR_EOF > 'smain.c'
  1023. #include <sys/types.h>
  1024. #include <stdio.h>
  1025. #include <pwd.h>
  1026. #include <string.h>
  1027. #include <signal.h>
  1028. #include "config.h"
  1029. #include "lastlog.h"
  1030.  
  1031. #ifndef    MAXENV
  1032. #define    MAXENV    64
  1033. #endif
  1034.  
  1035. char    name[BUFSIZ];
  1036. char    pass[BUFSIZ];
  1037. char    home[BUFSIZ];
  1038. char    prog[BUFSIZ];
  1039. char    mail[BUFSIZ];
  1040. char    oldname[BUFSIZ];
  1041. char    *newenvp[MAXENV];
  1042. int    newenvc = 0;
  1043. int    maxenv = MAXENV;
  1044. struct    passwd    pwent;
  1045.  
  1046. void    addenv ();
  1047. void    entry ();
  1048. void    sulog ();
  1049. void    subsystem ();
  1050. void    setup ();
  1051. void    motd ();
  1052. void    mailcheck ();
  1053. void    shell ();
  1054.  
  1055. extern    char    **environ;
  1056.  
  1057. int    main (argc, argv, envp)
  1058. int    argc;
  1059. char    **argv;
  1060. char    **envp;
  1061. {
  1062.     char    *getenv ();
  1063.     int    doshell;
  1064.     int    fakelogin = 0;
  1065.     int    amroot;
  1066.     struct    passwd    *pw;
  1067.     struct    passwd    *getpwuid ();
  1068.  
  1069.     while (*envp)            /* add inherited environment, */
  1070.         addenv (*envp++);    /* some variables change later */
  1071.  
  1072. #ifdef    TZ
  1073.     addenv (TZ);            /* set the default $TZ, if one */
  1074. #endif
  1075. #ifdef    HZ
  1076.     addenv (HZ);            /* set the default $HZ, if one */
  1077. #endif
  1078.     argc--; argv++;            /* shift out command name */
  1079.  
  1080.     if (argc > 0 && argv[0][0] == '-' && argv[0][1] == '\0') {
  1081.         fakelogin = 1;
  1082.         argc--; argv++;        /* shift ... */
  1083.     }
  1084.     if (argc > 0 && argv[0][0] != '-') {
  1085.         (void) strcpy (name, argv[0]);    /* use this login id */
  1086.         argc--; argv++;        /* shift ... */
  1087.     }
  1088.     doshell = argc == 0;        /* any arguments remaining? */
  1089.  
  1090.     if (pw = getpwuid (getuid ()))    /* need old user name */
  1091.         (void) strcpy (oldname, pw->pw_name);
  1092.     else                /* user ID MUST exist */
  1093.         goto failure;
  1094.  
  1095.     amroot = getuid () == 0;    /* currently am super user */
  1096.  
  1097.     if (! name[0])             /* use default user ID */
  1098.         (void) strcpy (name, "root");
  1099.  
  1100.     entry (name, &pwent);        /* get password file entry */
  1101.  
  1102.     if (pwent.pw_name == (char *) 0) { /* unknown user */
  1103.         (void) fprintf (stderr, "Unknown id: %s\n", pwent.pw_name);
  1104.         exit (1);
  1105.     }
  1106.  
  1107.     /*
  1108.      * Here we have a sticky situation.  Some accounts may have no
  1109.      * password entry in the password file.  So, we don't ask for a
  1110.      * password.  Others, have a blank password entered - you be the
  1111.      * judge.  The conditional compilation NOBLANK requires even
  1112.      * blank passwords to be prompted for.  This may well break
  1113.      * quite a few systems.  Use with discretion.
  1114.      */
  1115.  
  1116. #ifdef    NOBLANK
  1117.     if (! amroot && ! password ("Password:", pass))
  1118.         goto failure;
  1119. #else
  1120.     if (! amroot && (pwent.pw_name == (char *) 0 || pwent.pw_passwd)
  1121.             && ! password ("Password:", pass))
  1122.         goto failure;
  1123. #endif
  1124.                     /* check encrypted passwords ... */
  1125.     if (! amroot && ! valid (pass, &pwent)) {
  1126. failure:    sulog (0);        /* log failed attempt */
  1127.         puts ("Sorry.");
  1128.         exit (1);
  1129.     }
  1130. #ifdef    SULOG
  1131.     sulog (1);            /* save SU information */
  1132. #endif
  1133.     if (pwent.pw_uid == 0)
  1134.         addenv (SUPATH);
  1135.     else
  1136.         addenv (PATH);
  1137.  
  1138.     environ = newenvp;        /* make new environment active */
  1139.  
  1140.     if (getenv ("IFS"))        /* don't export user IFS ... */
  1141.         addenv ("IFS= \t\n");    /* ... instead, set a safe IFS */
  1142.  
  1143.     if (doshell && pwent.pw_shell[0] == '*') /* subsystem root required */
  1144.         subsystem ();        /* figure out what to execute */
  1145.  
  1146.     if (fakelogin)
  1147.         setup (&pwent);        /* set UID, GID, HOME, etc ... */
  1148.     else {
  1149.         if (setgid (pwent.pw_gid) || setuid (pwent.pw_uid))  {
  1150.             perror ("Can't set ID");
  1151.             exit (1);
  1152.         }
  1153.     }
  1154.     if (! doshell) {        /* execute arguments as command */
  1155.         if (! pwent.pw_shell)
  1156.             pwent.pw_shell = "/bin/sh";
  1157.  
  1158.         argv[-1] = pwent.pw_shell;
  1159.         (void) execv (pwent.pw_shell, &argv[-1]);
  1160.         (void) fprintf (stderr, "No shell\n");
  1161.         exit (1);
  1162.     }
  1163.     if (fakelogin) {
  1164. #ifdef    MOTD
  1165.         motd ();        /* print the message of the day */
  1166. #endif
  1167. #ifdef    MAILCHECK
  1168.         mailcheck ();        /* report on the status of mail */
  1169. #endif
  1170.         shell (pwent.pw_shell);    /* exec the shell finally. */
  1171.     } else {
  1172.         if (pwent.pw_shell == (char *) 0)
  1173.             pwent.pw_shell = "/bin/sh";
  1174.  
  1175.         execl (pwent.pw_shell, "su", (char *) 0);
  1176.         perror (pwent.pw_shell);
  1177.         exit (1);
  1178.     }
  1179.     /*NOTREACHED*/
  1180. }
  1181. SHAR_EOF
  1182. fi
  1183. if test -f 'pwconv.c'
  1184. then
  1185.     echo shar: "will not over-write existing file 'pwconv.c'"
  1186. else
  1187. cat << \SHAR_EOF > 'pwconv.c'
  1188. /*
  1189.  * pwconv - convert and update shadow password files
  1190.  *
  1191.  *    Pwconv copies the old password file information to a new shadow
  1192.  *    password file, merging entries from an optional existing shadow
  1193.  *    file.
  1194.  *
  1195.  *    The new password file is left in npasswd, the new shadow file is
  1196.  *    left in nshadow.  Existing shadow entries are copied as is.
  1197.  *    New entries are created with passwords which expire in 10000 days,
  1198.  *    with a last changed date of today, unless password aging
  1199.  *    information was already present.  Entries with blank passwords
  1200.  *    are not copied to the shadow file at all.
  1201.  */
  1202.  
  1203. #include <sys/types.h>
  1204. #include <stdio.h>
  1205. #include <fcntl.h>
  1206. #include <pwd.h>
  1207. #include "config.h"
  1208. #include "lastlog.h"
  1209. #include "shadow.h"
  1210.  
  1211. char    buf[BUFSIZ];
  1212.  
  1213. long    time ();
  1214. long    a64l ();
  1215.  
  1216. int    main ()
  1217. {
  1218.     long    today;
  1219.     struct    passwd    *pw;
  1220.     struct    passwd    *sgetpwent ();
  1221.     FILE    *pwd;
  1222.     FILE    *npwd;
  1223.     FILE    *shadow;
  1224.     struct    spwd    *spwd;
  1225.     struct    spwd    tspwd;
  1226.     int    fd;
  1227.  
  1228.     if (! (pwd = fopen (PWDFILE, "r"))) {
  1229.         perror (PWDFILE);
  1230.         return (1);
  1231.     }
  1232.     unlink ("npasswd");
  1233.     if ((fd = open ("npasswd", O_WRONLY|O_CREAT|O_EXCL, 0600)) < 0 ||
  1234.             ! (npwd = fdopen (fd, "w"))) {
  1235.         perror ("npasswd");
  1236.         return (1);
  1237.     }
  1238.     unlink  ("nshadow");
  1239.     if ((fd = open ("nshadow", O_WRONLY|O_CREAT|O_EXCL, 0600)) < 0 ||
  1240.             ! (shadow = fdopen (fd, "w"))) {
  1241.         perror ("nshadow");
  1242.         return (1);
  1243.     }
  1244.  
  1245.     (void) time (&today);
  1246.     today /= (24L * 60L * 60L);
  1247.  
  1248.     while (fgets (buf, BUFSIZ, pwd) == buf) {
  1249.         buf[strlen (buf) - 1] = '\0'; /* remove '\n' character */
  1250.  
  1251.         if (buf[0] == '#') {    /* comment line */
  1252.             (void) fprintf (npwd, "%s\n", buf);
  1253.             continue;
  1254.         }
  1255.         if (! (pw = sgetpwent (buf))) { /* copy bad lines verbatim */
  1256.             (void) fprintf (npwd, "%s\n", buf);
  1257.             continue;
  1258.         }
  1259.         if (pw->pw_passwd == (char *) 0) { /* no password, skip */
  1260.             (void) fprintf (npwd, "%s\n", buf);
  1261.             continue;
  1262.         }
  1263.         setspent ();        /* rewind old shadow file */
  1264.  
  1265.         if (spwd = getspnam (pw->pw_name)) {
  1266.             if (! putspent (spwd, shadow)) { /* copy old entry */
  1267.                 perror ("nshadow");
  1268.                 return (1);
  1269.             }
  1270.         } else {        /* need a new entry. */
  1271.             tspwd.sp_namp = pw->pw_name;
  1272.             tspwd.sp_pwdp = pw->pw_passwd;
  1273.             pw->pw_passwd = "x";
  1274.  
  1275.             if (pw->pw_age) { /* copy old password age stuff */
  1276.                 tspwd.sp_min = c64i (pw->pw_age[1]);
  1277.                 tspwd.sp_max = c64i (pw->pw_age[0]);
  1278.                 if (strlen (pw->pw_age) == 4)
  1279.                     tspwd.sp_lstchg = a64l (&pw->pw_age[2]);
  1280.                 else
  1281.                     tspwd.sp_lstchg = 0L;
  1282.  
  1283.                 /*
  1284.                  * Convert weeks to days
  1285.                  */
  1286.  
  1287.                 tspwd.sp_min *= 7;
  1288.                 tspwd.sp_max *= 7;
  1289.                 tspwd.sp_lstchg *= 7;
  1290.             } else {    /* fake up new password age stuff */
  1291.                 tspwd.sp_max = 10000;
  1292.                 tspwd.sp_min = 0;
  1293.                 tspwd.sp_lstchg = today;
  1294.             }
  1295.             if (! putspent (&tspwd, shadow)) { /* output entry */
  1296.                 perror ("nshadow");
  1297.                 return (1);
  1298.             }
  1299.         }
  1300.         (void) fprintf (npwd, "%s:%s:%d:%d:%s:%s:",
  1301.                 pw->pw_name, pw->pw_passwd ? pw->pw_passwd:"",
  1302.                 pw->pw_uid, pw->pw_gid,
  1303.                 pw->pw_gecos, pw->pw_dir);
  1304.  
  1305.         if (fprintf (npwd, "%s\n",
  1306.                 pw->pw_shell ? pw->pw_shell:"") == EOF) {
  1307.             perror ("npasswd");
  1308.             return (1);
  1309.         }
  1310.     }
  1311.     endspent ();
  1312.  
  1313.     if (ferror (npwd) || ferror (shadow)) {
  1314.         perror ("pwconv");
  1315.         (void) unlink ("npasswd");
  1316.         (void) unlink ("nshadow");
  1317.     }
  1318.     (void) fclose (pwd);
  1319.     (void) fclose (npwd);
  1320.     (void) fclose (shadow);
  1321.  
  1322.     return (0);
  1323. }
  1324. SHAR_EOF
  1325. fi
  1326. if test -f 'dialup.c'
  1327. then
  1328.     echo shar: "will not over-write existing file 'dialup.c'"
  1329. else
  1330. cat << \SHAR_EOF > 'dialup.c'
  1331. #include <stdio.h>
  1332. #include <string.h>
  1333. #include "dialup.h"
  1334.  
  1335. static    FILE    *dialpwd;
  1336.  
  1337. void    setduent ()
  1338. {
  1339.     if (dialpwd)
  1340.         rewind (dialpwd);
  1341.     else
  1342.         dialpwd = fopen (DIALPWD, "r");
  1343. }
  1344.  
  1345. void    endduent ()
  1346. {
  1347.     if (dialpwd)
  1348.         fclose (dialpwd);
  1349.  
  1350.     dialpwd = (FILE *) 0;
  1351. }
  1352.  
  1353. struct    dialup    *getduent ()
  1354. {
  1355.     static    struct    dialup    dialup;    /* static structure to point to */
  1356.     static    char    shell[64];    /* some space for a login shell */
  1357.     static    char    passwd[16];    /* some space for dialup password */
  1358.     char    buf[BUFSIZ];
  1359.     char    *cp;
  1360.  
  1361.     if (! dialpwd)
  1362.         setduent ();
  1363.  
  1364.     if (! dialpwd || feof (dialpwd))
  1365.         return ((struct dialup *) 0);
  1366.  
  1367.     while (fgets (buf, BUFSIZ, dialpwd) == buf)
  1368.         if (buf[0] == '#')
  1369.             continue;
  1370.  
  1371.     if (feof (dialpwd))
  1372.         return ((struct dialup *) 0);
  1373.  
  1374.     cp = strchr (buf, ':');
  1375.     if (cp - buf > sizeof shell)    /* something is fishy ... */
  1376.         return ((struct dialup *) 0);
  1377.  
  1378.     (void) strncpy (shell, buf, cp - buf);
  1379.     shell[cp - buf] = '\0';
  1380.  
  1381.     if (strlen (cp + 1) > sizeof passwd) /* something is REALLY fishy */
  1382.         return ((struct dialup *) 0);
  1383.  
  1384.     (void) strcpy (passwd, cp + 1);
  1385.     passwd[strlen (passwd) - 1] = '\0';
  1386.     if (cp = strchr (passwd, ':'))
  1387.         *cp = '\0';
  1388.  
  1389.     dialup.du_shell = shell;
  1390.     dialup.du_passwd = passwd;
  1391.  
  1392.     return (&dialup);
  1393. }
  1394.  
  1395. struct    dialup    *getdushell (shell)
  1396. char    *shell;
  1397. {
  1398.     struct    dialup    *dialup;
  1399.  
  1400.     while (dialup = getduent ())
  1401.         if (strcmp (shell, dialup->du_shell) == 0)
  1402.             return (dialup);
  1403.  
  1404.     return ((struct dialup *) 0);
  1405. }
  1406.  
  1407. int    isadialup (tty)
  1408. char    *tty;
  1409. {
  1410.     FILE    *fp;
  1411.     char    buf[BUFSIZ];
  1412.     int    dialup = 0;
  1413.  
  1414.     if (! (fp = fopen (DIALUPS, "r")))
  1415.         return (0);
  1416.  
  1417.     while (fgets (buf, BUFSIZ, fp) == buf) {
  1418.         buf[strlen (buf) - 1] = '\0';
  1419.  
  1420.         if (strcmp (buf, tty) == 0) {
  1421.             dialup = 1;
  1422.             break;
  1423.         }
  1424.     }
  1425.     fclose (fp);
  1426.  
  1427.     return (dialup);
  1428. }
  1429. SHAR_EOF
  1430. fi
  1431. if test -f 'dialchk.c'
  1432. then
  1433.     echo shar: "will not over-write existing file 'dialchk.c'"
  1434. else
  1435. cat << \SHAR_EOF > 'dialchk.c'
  1436. #include <stdio.h>
  1437. #include "config.h"
  1438. #include "dialup.h"
  1439.  
  1440. /*
  1441.  * Check for dialup password
  1442.  *
  1443.  *    dialcheck tests to see if tty is listed as being a dialup
  1444.  *    line.  If so, a dialup password may be required if the shell
  1445.  *    is listed as one which requires a second password.
  1446.  */
  1447.  
  1448. #ifdef    DIALUP
  1449. int    dialcheck (tty, shell)
  1450. char    *tty;
  1451. char    *shell;
  1452. {
  1453.     char    *crypt ();
  1454.     char    *getpass ();
  1455.     struct    dialup    *dialup;
  1456.     char    *pass;
  1457.     char    *cp;
  1458.  
  1459.     if (! isadialup (tty))
  1460.         return (1);
  1461.  
  1462.     if (! (dialup = getdushell (shell)))
  1463.         return (1);
  1464.  
  1465.     endduent ();
  1466.  
  1467.     if (dialup->du_passwd[0] == '\0')
  1468.         return (1);
  1469.  
  1470.     if (! (pass = getpass ("Dialup Password:")))
  1471.         return (0);
  1472.  
  1473.     cp = crypt (pass, dialup->du_passwd);
  1474.     return (strcmp (cp, dialup->du_passwd) == 0);
  1475. }
  1476. #endif
  1477. SHAR_EOF
  1478. fi
  1479. if test -f 'pwunconv.c'
  1480. then
  1481.     echo shar: "will not over-write existing file 'pwunconv.c'"
  1482. else
  1483. cat << \SHAR_EOF > 'pwunconv.c'
  1484. /*
  1485.  * pwunconv - restore old password file from shadow password file.
  1486.  *
  1487.  *    Pwunconv copies the password file information from the shadow
  1488.  *    password file, merging entries from an optional existing shadow
  1489.  *    file.
  1490.  *
  1491.  *    The new password file is left in npasswd.  There is no new
  1492.  *    shadow file.  Password aging information is translated where
  1493.  *    possible.
  1494.  */
  1495.  
  1496. #include <sys/types.h>
  1497. #include <stdio.h>
  1498. #include <fcntl.h>
  1499. #include <pwd.h>
  1500. #include "config.h"
  1501. #include "lastlog.h"
  1502. #include "shadow.h"
  1503.  
  1504. char    buf[BUFSIZ];
  1505. char    *l64a ();
  1506.  
  1507. int    main ()
  1508. {
  1509.     struct    passwd    *pw;
  1510.     struct    passwd    *sgetpwent ();
  1511.     FILE    *pwd;
  1512.     FILE    *npwd;
  1513.     struct    spwd    *spwd;
  1514.     int    fd;
  1515.  
  1516.     if (! (pwd = fopen (PWDFILE, "r"))) {
  1517.         perror (PWDFILE);
  1518.         return (1);
  1519.     }
  1520.     unlink ("npasswd");
  1521.     if ((fd = open ("npasswd", O_WRONLY|O_CREAT|O_EXCL, 0600)) < 0 ||
  1522.             ! (npwd = fdopen (fd, "w"))) {
  1523.         perror ("npasswd");
  1524.         return (1);
  1525.     }
  1526.     while (fgets (buf, BUFSIZ, pwd) == buf) {
  1527.         buf[strlen (buf) - 1] = '\0'; /* remove '\n' character */
  1528.  
  1529.         if (buf[0] == '#') {    /* comment line */
  1530.             (void) fprintf (npwd, "%s\n", buf);
  1531.             continue;
  1532.         }
  1533.         if (! (pw = sgetpwent (buf))) { /* copy bad lines verbatim */
  1534.             (void) fprintf (npwd, "%s\n", buf);
  1535.             continue;
  1536.         }
  1537.         setspent ();        /* rewind shadow file */
  1538.  
  1539.         if (! (spwd = getspnam (pw->pw_name))) {
  1540.             (void) fprintf (npwd, "%s\n", buf);
  1541.             continue;
  1542.         }
  1543.         pw->pw_passwd = spwd->sp_pwdp;
  1544.  
  1545.     /*
  1546.      * Password aging works differently in the two different systems.
  1547.      * With shadow password files you apparently must have some aging
  1548.      * information.  The maxweeks or minweeks may not map exactly.
  1549.      * In pwconv we set max == 10000, which is about 30 years.  Here
  1550.      * we have to undo that kludge.  So, if maxdays == 10000, no aging
  1551.      * information is put into the new file.  Otherwise, the days are
  1552.      * converted to weeks and so on.
  1553.      */
  1554.  
  1555.         if (spwd->sp_max > (63*7) && spwd->sp_max < 10000)
  1556.             spwd->sp_max = (63*7); /* 10000 is infinity this week */
  1557.  
  1558.         if (spwd->sp_min >= 0 && spwd->sp_min <= 63*7 &&
  1559.                 spwd->sp_max >= 0 && spwd->sp_max <= 63*7) {
  1560.             spwd->sp_max /= 7;    /* turn it into weeks */
  1561.             spwd->sp_min /= 7;
  1562.             spwd->sp_lstchg /= 7;
  1563.             pw->pw_age = l64a ((long) spwd->sp_lstchg * (64L*64L) +
  1564.                           spwd->sp_min * (64L) +
  1565.                           spwd->sp_max);
  1566.         } else
  1567.             pw->pw_age = (char *) 0;
  1568.  
  1569.         if (pw->pw_age)
  1570.             (void) fprintf (npwd, "%s:%s,%s:%d:%d:%s:%s:%s\n",
  1571.                 pw->pw_name, pw->pw_passwd ? pw->pw_passwd:"",
  1572.                 pw->pw_age, pw->pw_uid, pw->pw_gid,
  1573.                 pw->pw_gecos, pw->pw_dir,
  1574.                 pw->pw_shell ? pw->pw_shell:"");
  1575.         else
  1576.             (void) fprintf (npwd, "%s:%s:%d:%d:%s:%s:%s\n",
  1577.                 pw->pw_name, pw->pw_passwd ? pw->pw_passwd:"",
  1578.                 pw->pw_uid, pw->pw_gid,
  1579.                 pw->pw_gecos, pw->pw_dir,
  1580.                 pw->pw_shell ? pw->pw_shell:"");
  1581.     }
  1582.     endspent ();
  1583.  
  1584.     if (ferror (npwd)) {
  1585.         perror ("pwunconv");
  1586.         (void) unlink ("npasswd");
  1587.     }
  1588.     (void) fclose (npwd);
  1589.     (void) fclose (pwd);
  1590.     return (0);
  1591. }
  1592. SHAR_EOF
  1593. fi
  1594. exit 0
  1595. #    End of shell archive
  1596.